home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / system-config-printer / cupspk.py < prev    next >
Encoding:
Python Source  |  2009-05-05  |  26.2 KB  |  742 lines

  1. # vim: set ts=4 sw=4 et: coding=UTF-8
  2. #
  3. # Copyright (C) 2008 Novell, Inc.
  4. # Copyright (C) 2009 Red Hat, Inc.
  5. # Copyright (C) 2009 Tim Waugh <twaugh@redhat.com>
  6. #
  7. # Authors: Vincent Untz
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. #
  23.  
  24. # check FIXME/TODO here
  25. # check FIXME/TODO in cups-pk-helper
  26. # define fine-grained policy (more than one level of permission)
  27. # add missing methods
  28.  
  29. import os
  30. import sys
  31.  
  32. import tempfile
  33.  
  34. import cups
  35. import dbus
  36. import gtk
  37.  
  38. from dbus.mainloop.glib import DBusGMainLoop
  39. DBusGMainLoop(set_as_default=True)
  40.  
  41. PK_AUTH_NAME  = 'org.freedesktop.PolicyKit.AuthenticationAgent'
  42. PK_AUTH_PATH  = '/'
  43. PK_AUTH_IFACE = 'org.freedesktop.PolicyKit.AuthenticationAgent'
  44.  
  45. CUPS_PK_NAME  = 'org.opensuse.CupsPkHelper.Mechanism'
  46. CUPS_PK_PATH  = '/'
  47. CUPS_PK_IFACE = 'org.opensuse.CupsPkHelper.Mechanism'
  48.  
  49. CUPS_PK_NEED_AUTH = 'org.opensuse.CupsPkHelper.Mechanism.NotPrivileged'
  50.  
  51.  
  52. pk_auth_ret = False
  53. pk_auth_error = None
  54. pk_auth_running = False
  55. pk_auth_done = False
  56.  
  57. def _pk_auth_reply_handler(ret):
  58.     global pk_auth_ret
  59.     global pk_auth_done
  60.  
  61.     pk_auth_ret = ret
  62.     pk_auth_done = True
  63.  
  64. def _pk_auth_error_handler(e):
  65.     global pk_auth_error
  66.     global pk_auth_done
  67.  
  68.     pk_auth_error = str(e)
  69.     pk_auth_done = True
  70.  
  71.  
  72. # we can't subclass cups.Connection, even when adding
  73. # Py_TPFLAGS_BASETYPE to cupsconnection.c
  74. # So we'll hack this...
  75. class Connection:
  76.     def __init__(self, host, port, encryption):
  77.         self._parent = None
  78.  
  79.         try:
  80.             self._session_bus = dbus.SessionBus()
  81.             self._system_bus = dbus.SystemBus()
  82.         except dbus.exceptions.DBusException:
  83.             # One or other bus not running.
  84.             self._session_bus = self._system_bus = None
  85.  
  86.         self._connection = cups.Connection(host=host,
  87.                                            port=port,
  88.                                            encryption=encryption)
  89.  
  90.         self._hack_subclass()
  91.  
  92.  
  93.     def _hack_subclass(self):
  94.         # here's how to subclass without really subclassing. Just provide
  95.         # the same methods
  96.         methodtype = type(self._connection.getPrinters)
  97.         for fname in dir(self._connection):
  98.             if fname[0] == '_':
  99.                 continue
  100.             fn = getattr(self._connection, fname)
  101.             if type(fn) != methodtype:
  102.                 continue
  103.             if not hasattr(self, fname):
  104.                 setattr(self, fname, fn.__call__)
  105.  
  106.  
  107.     def set_parent(self, parent):
  108.         self._parent = parent
  109.  
  110.  
  111.     def _get_cups_pk(self):
  112.         try:
  113.             object = self._system_bus.get_object(CUPS_PK_NAME, CUPS_PK_PATH)
  114.             return dbus.Interface(object, CUPS_PK_IFACE)
  115.         except dbus.exceptions.DBusException:
  116.             # Failed to get object or interface.
  117.             return None
  118.         except AttributeError:
  119.             # No system D-Bus
  120.             return None
  121.  
  122.  
  123.     def _obtain_auth(self, action, xid = 0):
  124.         global pk_auth_ret
  125.         global pk_auth_error
  126.         global pk_auth_done
  127.         global pk_auth_running
  128.  
  129.         if pk_auth_running:
  130.             # FIXME: raise an exception: this should really never happen
  131.             return False
  132.  
  133.         pk_auth_ret = False
  134.         pk_auth_error = None
  135.         pk_auth_done = False
  136.  
  137.         pk_auth_object = self._session_bus.get_object(PK_AUTH_NAME, PK_AUTH_PATH)
  138.         pk_auth = dbus.Interface(pk_auth_object, PK_AUTH_IFACE)
  139.  
  140.         # We're doing this dbus call asynchronously because we want to not
  141.         # freeze the UI while a menu is being destroyed. And the windows might
  142.         # need some repainting while the authorization dialog is displayed.
  143.         pk_auth_running = True
  144.  
  145.         pk_auth.ObtainAuthorization(action, dbus.UInt32(xid), dbus.UInt32(os.getpid()), reply_handler=_pk_auth_reply_handler, error_handler=_pk_auth_error_handler)
  146.  
  147.         while not pk_auth_done:
  148.             gtk.main_iteration(True)
  149.  
  150.         pk_auth_running = False
  151.  
  152.         if pk_auth_error != None:
  153.             raise dbus.exceptions.DBusException(pk_auth_error)
  154.  
  155.         if not type(pk_auth_ret) == dbus.Boolean:
  156.             return False
  157.  
  158.         return pk_auth_ret != 0
  159.  
  160.  
  161.     def _handle_exception_with_auth(self, e):
  162.         if e.get_dbus_name() != CUPS_PK_NEED_AUTH:
  163.             return False
  164.  
  165.         tokens = e.get_dbus_message().split(' ', 2)
  166.         if len(tokens) != 3:
  167.             return False
  168.  
  169.         try:
  170.             xid = 0
  171.             if self._parent and getattr(self._parent, 'window') and getattr(self._parent.window, 'xid'):
  172.                 xid = self._parent.window.xid
  173.  
  174.             # FIXME: is xid working?
  175.             ret = self._obtain_auth(tokens[0], xid)
  176.         except dbus.exceptions.DBusException:
  177.             return False
  178.  
  179.         if not ret:
  180.             raise cups.IPPError(cups.IPP_NOT_AUTHORIZED, 'pkcancel')
  181.  
  182.         return True
  183.  
  184.  
  185.     def _call_with_pk_and_fallback(self, use_fallback, pk_function_name, pk_args, fallback_function, *args, **kwds):
  186.         pk_function = None
  187.  
  188.         if not use_fallback:
  189.             cups_pk = self._get_cups_pk()
  190.             if cups_pk:
  191.                 try:
  192.                     pk_function = cups_pk.get_dbus_method(pk_function_name)
  193.                 except dbus.exceptions.DBusException:
  194.                     pass
  195.  
  196.         if use_fallback or not pk_function:
  197.             return fallback_function(*args, **kwds)
  198.  
  199.         pk_retval = 'PolicyKit communication issue'
  200.  
  201.         while True:
  202.             try:
  203.                 # FIXME: async call or not?
  204.                 pk_retval = pk_function(*pk_args)
  205.  
  206.                 # if the PK call has more than one return values, we pop the
  207.                 # first one as the error message
  208.                 if type(pk_retval) == tuple:
  209.                     retval = pk_retval[1:]
  210.                     # if there's no error, then we can safely return what we
  211.                     # got
  212.                     if pk_retval[0] == '':
  213.                         # if there's only one item left in the tuple, we don't
  214.                         # want to return the tuple, but the item
  215.                         if len(retval) == 1:
  216.                             return retval[0]
  217.                         else:
  218.                             return retval
  219.                 break
  220.             except dbus.exceptions.DBusException, e:
  221.                 if not self._handle_exception_with_auth(e):
  222.                     break
  223.  
  224.         # The PolicyKit call did not work (either a PK-error and we got a dbus
  225.         # exception that wasn't handled, or an error in the mechanism itself)
  226.         if pk_retval != '':
  227.             print >>sys.stderr, 'PolicyKit call to %s did not work: %s' % (pk_function_name, pk_retval)
  228.             return fallback_function(*args, **kwds)
  229.  
  230.  
  231.     def _args_to_tuple(self, types, *args):
  232.         retval = [ False ]
  233.  
  234.         if len(types) != len(args):
  235.             retval[0] = True
  236.             # We do this to have the right length for the returned value
  237.             retval.extend(types)
  238.             return tuple(types)
  239.  
  240.         exception = False
  241.  
  242.         for i in range(len(types)):
  243.             if type(args[i]) != types[i]:
  244.                 if types[i] == str and type(args[i]) == unicode:
  245.                     # we accept a mix between unicode and str
  246.                     pass
  247.                 elif types[i] == str and type(args[i]) == int:
  248.                     # we accept a mix between int and str
  249.                     retval.append(str(args[i]))
  250.                     continue
  251.                 elif types[i] == str and type(args[i]) == float:
  252.                     # we accept a mix between float and str
  253.                     retval.append(str(args[i]))
  254.                     continue
  255.                 elif types[i] == str and type(args[i]) == bool:
  256.                     # we accept a mix between bool and str
  257.                     retval.append(str(args[i]))
  258.                     continue
  259.                 elif types[i] == str and args[i] == None:
  260.                     # None is an empty string for dbus
  261.                     retval.append('')
  262.                     continue
  263.                 elif types[i] == list and type(args[i]) == tuple:
  264.                     # we accept a mix between list and tuple
  265.                     retval.append(list(args[i]))
  266.                     continue
  267.                 elif types[i] == list and args[i] == None:
  268.                     # None is an empty list
  269.                     retval.append([])
  270.                     continue
  271.                 else:
  272.                     exception = True
  273.             retval.append(args[i])
  274.  
  275.         retval[0] = exception
  276.  
  277.         return tuple(retval)
  278.  
  279.  
  280.     def _kwds_to_vars(self, names, **kwds):
  281.         ret = []
  282.  
  283.         for name in names:
  284.             if kwds.has_key(name):
  285.                 ret.append(kwds[name])
  286.             else:
  287.                 ret.append('')
  288.  
  289.         return tuple(ret)
  290.  
  291.  
  292. #    getPrinters
  293. #    getDests
  294. #    getClasses
  295. #    getPPDs
  296. #    getServerPPD
  297. #    getDocument
  298. #    getDevices
  299. #    getJobs
  300. #    getJobAttributes
  301.  
  302.     def cancelJob(self, *args, **kwds):
  303.         (use_pycups, jobid) = self._args_to_tuple([int], *args)
  304.         pk_args = (jobid, )
  305.  
  306.         self._call_with_pk_and_fallback(use_pycups,
  307.                                         'JobCancel', pk_args,
  308.                                         self._connection.cancelJob,
  309.                                         *args, **kwds)
  310.  
  311.  
  312. #    cancelAllJobs
  313. #    authenticateJob
  314.     def setJobHoldUntil(self, *args, **kwds):
  315.         (use_pycups, jobid, job_hold_until) = self._args_to_tuple([int, str], *args)
  316.         pk_args = (jobid, job_hold_until, )
  317.  
  318.         self._call_with_pk_and_fallback(use_pycups,
  319.                                         'JobSetHoldUntil', pk_args,
  320.                                         self._connection.setJobHoldUntil,
  321.                                         *args, **kwds)
  322.  
  323.     def restartJob(self, *args, **kwds):
  324.         (use_pycups, jobid) = self._args_to_tuple([int], *args)
  325.         pk_args = (jobid, )
  326.         
  327.         self._call_with_pk_and_fallback(use_pycups,
  328.                                         'JobRestart', pk_args,
  329.                                         self._connection.restartJob,
  330.                                         *args, **kwds)
  331.  
  332.     def getFile(self, *args, **kwds):
  333.         ''' Keeping this as an alternative for the code.
  334.             We don't use it because it's not possible to know if the call was a
  335.             PK-one (and so we push the content of a temporary filename to fd or
  336.             file) or a non-PK-one (in which case nothing should be done).
  337.  
  338.                 filename = None
  339.                 fd = None
  340.                 file = None
  341.                 if use_pycups:
  342.                     if len(kwds) != 1:
  343.                         use_pycups = True
  344.                     elif kwds.has_key('filename'):
  345.                         filename = kwds['filename']
  346.                     elif kwds.has_key('fd'):
  347.                         fd = kwds['fd']
  348.                     elif kwds.has_key('file'):
  349.                         file = kwds['file']
  350.                     else:
  351.                         use_pycups = True
  352.  
  353.                     if fd or file:
  354.         '''
  355.  
  356.         file_object = None
  357.         fd = None
  358.         if len(args) == 2:
  359.             (use_pycups, resource, filename) = self._args_to_tuple([str, str], *args)
  360.         else:
  361.             (use_pycups, resource) = self._args_to_tuple([str], *args)
  362.             if kwds.has_key('filename'):
  363.                 filename = kwds['filename']
  364.             elif kwds.has_key('fd'):
  365.                 fd = kwds['fd']
  366.             elif kwds.has_key('file'):
  367.                 file_object = kwds['file']
  368.             else:
  369.                 if not use_pycups:
  370.                     raise TypeError()
  371.                 else:
  372.                     filename = None
  373.  
  374.         if (not use_pycups) and (fd != None or file_object != None):
  375.             (tmpfd, tmpfname) = tempfile.mkstemp()
  376.             os.close (tmpfd)
  377.  
  378.             pk_args = (resource, tmpfname)
  379.             self._call_with_pk_and_fallback(use_pycups,
  380.                                             'FileGet', pk_args,
  381.                                             self._connection.getFile,
  382.                                             *args, **kwds)
  383.  
  384.             tmpfd = os.open (tmpfname, os.O_RDONLY)
  385.             tmpfile = os.fdopen (tmpfd, 'r')
  386.             tmpfile.seek (0)
  387.  
  388.             if fd != None:
  389.                 os.lseek (fd, 0, os.SEEK_SET)
  390.                 line = tmpfile.readline()
  391.                 while line != '':
  392.                     os.write (fd, line)
  393.                     line = tmpfile.readline()
  394.             else:
  395.                 file_object.seek (0)
  396.                 line = tmpfile.readline()
  397.                 while line != '':
  398.                     file_object.write (line)
  399.                     line = tmpfile.readline()
  400.  
  401.             tmpfile.close ()
  402.             os.remove (tmpfname)
  403.         else:
  404.             pk_args = (resource, filename)
  405.  
  406.             self._call_with_pk_and_fallback(use_pycups,
  407.                                             'FileGet', pk_args,
  408.                                             self._connection.getFile,
  409.                                             *args, **kwds)
  410.  
  411.  
  412.     def putFile(self, *args, **kwds):
  413.         if len(args) == 2:
  414.             (use_pycups, resource, filename) = self._args_to_tuple([str, str], *args)
  415.         else:
  416.             (use_pycups, resource) = self._args_to_tuple([str], *args)
  417.             if kwds.has_key('filename'):
  418.                 filename = kwds['filename']
  419.             elif kwds.has_key('fd'):
  420.                 fd = kwds['fd']
  421.             elif kwds.has_key('file'):
  422.                 file_object = kwds['file']
  423.             else:
  424.                 if not use_pycups:
  425.                     raise TypeError()
  426.                 else:
  427.                     filename = None
  428.  
  429.         if (not use_pycups) and (fd != None or file_object != None):
  430.             (tmpfd, tmpfname) = tempfile.mkstemp()
  431.             os.lseek (tmpfd, 0, os.SEEK_SET)
  432.  
  433.             if fd != None:
  434.                 os.lseek (fd, 0, os.SEEK_SET)
  435.                 buf = os.read (fd, 512)
  436.                 while buf != '':
  437.                     os.write (tmpfd, buf)
  438.                     buf = os.read (fd, 512)
  439.             else:
  440.                 file_object.seek (0)
  441.                 line = file_object.readline ()
  442.                 while line != '':
  443.                     os.write (tmpfd, line)
  444.                     line = file_object.readline ()
  445.  
  446.             os.close (tmpfd)
  447.  
  448.             pk_args = (resource, tmpfname)
  449.  
  450.             self._call_with_pk_and_fallback(use_pycups,
  451.                                             'FilePut', pk_args,
  452.                                             self._connection.putFile,
  453.                                             *args, **kwds)
  454.  
  455.             os.remove (tmpfname)
  456.         else:
  457.  
  458.             pk_args = (resource, filename)
  459.  
  460.             self._call_with_pk_and_fallback(use_pycups,
  461.                                             'FilePut', pk_args,
  462.                                             self._connection.putFile,
  463.                                             *args, **kwds)
  464.  
  465.  
  466.     def addPrinter(self, *args, **kwds):
  467.         (use_pycups, name) = self._args_to_tuple([str], *args)
  468.         (filename, ppdname, info, location, device, ppd) = self._kwds_to_vars(['filename', 'ppdname', 'info', 'location', 'device', 'ppd'], **kwds)
  469.  
  470.         need_unlink = False
  471.         if not ppdname and not filename and ppd:
  472.             (fd, filename) = tempfile.mkstemp ()
  473.             ppd.writeFd(fd)
  474.             os.close(fd)
  475.             need_unlink = True
  476.  
  477.         if filename and not ppdname:
  478.             pk_args = (name, device, filename, info, location)
  479.             self._call_with_pk_and_fallback(use_pycups,
  480.                                             'PrinterAddWithPpdFile', pk_args,
  481.                                             self._connection.addPrinter,
  482.                                             *args, **kwds)
  483.             if need_unlink:
  484.                 os.unlink(filename)
  485.         else:
  486.             pk_args = (name, device, ppdname, info, location)
  487.             self._call_with_pk_and_fallback(use_pycups,
  488.                                             'PrinterAdd', pk_args,
  489.                                             self._connection.addPrinter,
  490.                                             *args, **kwds)
  491.  
  492.  
  493.     def setPrinterDevice(self, *args, **kwds):
  494.         (use_pycups, name, device) = self._args_to_tuple([str, str], *args)
  495.         pk_args = (name, device)
  496.  
  497.         self._call_with_pk_and_fallback(use_pycups,
  498.                                         'PrinterSetDevice', pk_args,
  499.                                         self._connection.setPrinterDevice,
  500.                                         *args, **kwds)
  501.  
  502.  
  503.     def setPrinterInfo(self, *args, **kwds):
  504.         (use_pycups, name, info) = self._args_to_tuple([str, str], *args)
  505.         pk_args = (name, info)
  506.  
  507.         self._call_with_pk_and_fallback(use_pycups,
  508.                                         'PrinterSetInfo', pk_args,
  509.                                         self._connection.setPrinterInfo,
  510.                                         *args, **kwds)
  511.  
  512.  
  513.     def setPrinterLocation(self, *args, **kwds):
  514.         (use_pycups, name, location) = self._args_to_tuple([str, str], *args)
  515.         pk_args = (name, location)
  516.  
  517.         self._call_with_pk_and_fallback(use_pycups,
  518.                                         'PrinterSetLocation', pk_args,
  519.                                         self._connection.setPrinterLocation,
  520.                                         *args, **kwds)
  521.  
  522.  
  523.     def setPrinterShared(self, *args, **kwds):
  524.         (use_pycups, name, shared) = self._args_to_tuple([str, bool], *args)
  525.         pk_args = (name, shared)
  526.  
  527.         self._call_with_pk_and_fallback(use_pycups,
  528.                                         'PrinterSetShared', pk_args,
  529.                                         self._connection.setPrinterShared,
  530.                                         *args, **kwds)
  531.  
  532.  
  533.     def setPrinterJobSheets(self, *args, **kwds):
  534.         (use_pycups, name, start, end) = self._args_to_tuple([str, str, str], *args)
  535.         pk_args = (name, start, end)
  536.  
  537.         self._call_with_pk_and_fallback(use_pycups,
  538.                                         'PrinterSetJobSheets', pk_args,
  539.                                         self._connection.setPrinterJobSheets,
  540.                                         *args, **kwds)
  541.  
  542.  
  543.     def setPrinterErrorPolicy(self, *args, **kwds):
  544.         (use_pycups, name, policy) = self._args_to_tuple([str, str], *args)
  545.         pk_args = (name, policy)
  546.  
  547.         self._call_with_pk_and_fallback(use_pycups,
  548.                                         'PrinterSetErrorPolicy', pk_args,
  549.                                         self._connection.setPrinterErrorPolicy,
  550.                                         *args, **kwds)
  551.  
  552.  
  553.     def setPrinterOpPolicy(self, *args, **kwds):
  554.         (use_pycups, name, policy) = self._args_to_tuple([str, str], *args)
  555.         pk_args = (name, policy)
  556.  
  557.         self._call_with_pk_and_fallback(use_pycups,
  558.                                         'PrinterSetOpPolicy', pk_args,
  559.                                         self._connection.setPrinterOpPolicy,
  560.                                         *args, **kwds)
  561.  
  562.  
  563.     def setPrinterUsersAllowed(self, *args, **kwds):
  564.         (use_pycups, name, users) = self._args_to_tuple([str, list], *args)
  565.         pk_args = (name, users)
  566.  
  567.         self._call_with_pk_and_fallback(use_pycups,
  568.                                         'PrinterSetUsersAllowed', pk_args,
  569.                                         self._connection.setPrinterUsersAllowed,
  570.                                         *args, **kwds)
  571.  
  572.  
  573.     def setPrinterUsersDenied(self, *args, **kwds):
  574.         (use_pycups, name, users) = self._args_to_tuple([str, list], *args)
  575.         pk_args = (name, users)
  576.  
  577.         self._call_with_pk_and_fallback(use_pycups,
  578.                                         'PrinterSetUsersDenied', pk_args,
  579.                                         self._connection.setPrinterUsersDenied,
  580.                                         *args, **kwds)
  581.  
  582.     def addPrinterOptionDefault(self, *args, **kwds):
  583.         # The values can be either a single string, or a list of strings, so
  584.         # we have to handle this
  585.         (use_pycups, name, option, value) = self._args_to_tuple([str, str, str], *args)
  586.         # success
  587.         if not use_pycups:
  588.             values = (value,)
  589.         # okay, maybe we directly have values
  590.         else:
  591.             (use_pycups, name, option, values) = self._args_to_tuple([str, str, list], *args)
  592.         pk_args = (name, option, values)
  593.  
  594.         self._call_with_pk_and_fallback(use_pycups,
  595.                                         'PrinterAddOptionDefault', pk_args,
  596.                                         self._connection.addPrinterOptionDefault,
  597.                                         *args, **kwds)
  598.  
  599.  
  600.     def deletePrinterOptionDefault(self, *args, **kwds):
  601.         (use_pycups, name, option) = self._args_to_tuple([str, str], *args)
  602.         pk_args = (name, option)
  603.  
  604.         self._call_with_pk_and_fallback(use_pycups,
  605.                                         'PrinterDeleteOptionDefault', pk_args,
  606.                                         self._connection.deletePrinterOptionDefault,
  607.                                         *args, **kwds)
  608.  
  609.  
  610.     def deletePrinter(self, *args, **kwds):
  611.         (use_pycups, name) = self._args_to_tuple([str], *args)
  612.         pk_args = (name,)
  613.  
  614.         self._call_with_pk_and_fallback(use_pycups,
  615.                                         'PrinterDelete', pk_args,
  616.                                         self._connection.deletePrinter,
  617.                                         *args, **kwds)
  618.  
  619. #    getPrinterAttributes
  620.  
  621.     def addPrinterToClass(self, *args, **kwds):
  622.         (use_pycups, printer, name) = self._args_to_tuple([str, str], *args)
  623.         pk_args = (name, printer)
  624.  
  625.         self._call_with_pk_and_fallback(use_pycups,
  626.                                         'ClassAddPrinter', pk_args,
  627.                                         self._connection.addPrinterToClass,
  628.                                         *args, **kwds)
  629.  
  630.  
  631.     def deletePrinterFromClass(self, *args, **kwds):
  632.         (use_pycups, printer, name) = self._args_to_tuple([str, str], *args)
  633.         pk_args = (name, printer)
  634.  
  635.         self._call_with_pk_and_fallback(use_pycups,
  636.                                         'ClassDeletePrinter', pk_args,
  637.                                         self._connection.deletePrinterFromClass,
  638.                                         *args, **kwds)
  639.  
  640.  
  641.     def deleteClass(self, *args, **kwds):
  642.         (use_pycups, name) = self._args_to_tuple([str], *args)
  643.         pk_args = (name,)
  644.  
  645.         self._call_with_pk_and_fallback(use_pycups,
  646.                                         'ClassDelete', pk_args,
  647.                                         self._connection.deleteClass,
  648.                                         *args, **kwds)
  649.  
  650. #    getDefault
  651.  
  652.     def setDefault(self, *args, **kwds):
  653.         (use_pycups, name) = self._args_to_tuple([str], *args)
  654.         pk_args = (name,)
  655.  
  656.         self._call_with_pk_and_fallback(use_pycups,
  657.                                         'PrinterSetDefault', pk_args,
  658.                                         self._connection.setDefault,
  659.                                         *args, **kwds)
  660.  
  661. #    getPPD
  662.  
  663.     def enablePrinter(self, *args, **kwds):
  664.         (use_pycups, name) = self._args_to_tuple([str], *args)
  665.         pk_args = (name, True)
  666.  
  667.         self._call_with_pk_and_fallback(use_pycups,
  668.                                         'PrinterSetEnabled', pk_args,
  669.                                         self._connection.enablePrinter,
  670.                                         *args, **kwds)
  671.  
  672.  
  673.     def disablePrinter(self, *args, **kwds):
  674.         (use_pycups, name) = self._args_to_tuple([str], *args)
  675.         pk_args = (name, False)
  676.  
  677.         self._call_with_pk_and_fallback(use_pycups,
  678.                                         'PrinterSetEnabled', pk_args,
  679.                                         self._connection.enablePrinter,
  680.                                         *args, **kwds)
  681.  
  682.  
  683.     def acceptJobs(self, *args, **kwds):
  684.         (use_pycups, name) = self._args_to_tuple([str], *args)
  685.         pk_args = (name, True, '')
  686.  
  687.         self._call_with_pk_and_fallback(use_pycups,
  688.                                         'PrinterSetAcceptJobs', pk_args,
  689.                                         self._connection.acceptJobs,
  690.                                         *args, **kwds)
  691.  
  692.  
  693.     def rejectJobs(self, *args, **kwds):
  694.         (use_pycups, name) = self._args_to_tuple([str], *args)
  695.         (reason,) = self._kwds_to_vars(['reason'], **kwds)
  696.         pk_args = (name, False, reason)
  697.  
  698.         self._call_with_pk_and_fallback(use_pycups,
  699.                                         'PrinterSetAcceptJobs', pk_args,
  700.                                         self._connection.rejectJobs,
  701.                                         *args, **kwds)
  702.  
  703.  
  704. #    printTestPage
  705.  
  706.     def adminGetServerSettings(self, *args, **kwds):
  707.         use_pycups = False
  708.         pk_args = ()
  709.  
  710.         result = self._call_with_pk_and_fallback(use_pycups,
  711.                                                'ServerGetSettings', pk_args,
  712.                                                self._connection.adminGetServerSettings,
  713.                                                *args, **kwds)
  714.         settings = {}
  715.         if result != None:
  716.             for i in result.keys():
  717.                 if type(i) == 'dbus.String':
  718.                     settings[i.encode()] = result[i].encode()
  719.                 else:
  720.                     settings[i] = result[i]
  721.  
  722.         return settings
  723.  
  724.  
  725.     def adminSetServerSettings(self, *args, **kwds):
  726.         (use_pycups, settings) = self._args_to_tuple([dict], *args)
  727.         pk_args = (settings,)
  728.  
  729.         self._call_with_pk_and_fallback(use_pycups,
  730.                                         'ServerSetSettings', pk_args,
  731.                                         self._connection.adminSetServerSettings,
  732.                                         *args, **kwds)
  733.  
  734.  
  735. #    getSubscriptions
  736. #    createSubscription
  737. #    getNotifications
  738. #    cancelSubscription
  739. #    renewSubscription
  740. #    printFile
  741. #    printFiles
  742.